package com.hzdracom.epubreader.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import logic.util.FileUtil;
import net.nightwhistler.htmlspanner.FontFamily;
import net.nightwhistler.htmlspanner.style.Style.BorderStyle;
import android.content.Context;
import android.text.TextUtils;

import com.hzdracom.epubreader.consts.EpubConst;
import com.shwread.android.qysw.QyReaderApp;
import com.shwread.http.util.Logger;

/**
 * CSS自定义样式解析
 * @author QY
 * @date 2015年8月28日 下午3:34:06
 */
public class CSSHelp
{
	
	/*******************  body  *******************/
	public static class Body{
		public static final String TAG_STYLE_ID = "body";
		public static final String TAG_BACKGROUND = "background";
		public static final String TAG_FONT_SIZE = "font-size";
		public static final String TAG_LINE_HEIGHT = "line-height";
		
		public int                 font_size;
		public int                 line_height;
		public String              background;
		@Override
        public String toString() {
	        return "Body [font_size=" + font_size + ", line_height=" + line_height + ", background=" + background + "]";
        }
	}
	/*******************  someonesaid 引文  *******************/
	public static class Someonesaid{
		public static final String TAG_STYLE_ID = "someonesaid";
		public static final String TAG_TEXT_INDENT = "text-indent";
		public static final String TAG_FONT_FAMILY = "font-family";
		public static final String TAG_PADDING = "padding";
		public static final String TAG_BORDER_TOP_WIDTH = "border-top-width";
		public static final String TAG_BORDER_TOP_STYLE = "border-top-style";
		public static final String TAG_BORDER_TOP_COLOR = "border-top-color";
		public static final String TAG_BORDER_BOTTOM_WIDTH = "border-bottom-width";
		public static final String TAG_BORDER_BOTTOM_STYLE = "border-bottom-style";
		public static final String TAG_BORDER_BOTTOM_COLOR = "border-bottom-color";
		
		public int                 text_indent;
		public int                 padding;
		public FontFamily          font_family;
		public String              border_top_color;
		public BorderStyle         border_top_style;
		public int                 border_top_width;
		public String              border_bottom_color;
		public BorderStyle         border_bottom_style;
		public int                 border_bottom_width;
		@Override
        public String toString() {
	        return "Someonesaid [text_indent=" + text_indent + ", padding=" + padding + ", font_family=" + font_family + ", border_top_color=" + border_top_color + ", border_top_style=" + border_top_style + ", border_top_width=" + border_top_width + ", border_bottom_color=" + border_bottom_color + ", border_bottom_style=" + border_bottom_style + ", border_bottom_width=" + border_bottom_width + "]";
        }
	}
	/*******************  summary 摘要  *******************/
	public static class Summary{
		public static final String TAG_STYLE_ID = "summary";
		public static final String TAG_MARGIN_LEFT = "margin-left";
		public static final String TAG_MARGIN_RIGHT = "margin-right";
		
		public int                 margin_left;
		public int                 margin_right;
		@Override
        public String toString() {
	        return "Summary [margin_left=" + margin_left + ", margin_right=" + margin_right + "]";
        }
	}
	
	private static Body body;
	public static Body getBody() {
		if(null == body){
			body = new Body();
			body.background = "#FFFFFF";
			body.font_size = 16;
			body.line_height = 22;
		}
	    return body;
    }
	
	private static Someonesaid someonesaid;
	public static Someonesaid getSomeonesaid(){
		if(null == someonesaid){ 
//			final String defaultColor = "#FF00FF";
			final String defaultColor = "#BBD575";
			someonesaid = new Someonesaid();
			someonesaid.border_top_color = defaultColor;
			someonesaid.border_top_style = BorderStyle.SOLID;
			someonesaid.border_top_width = 5;
			someonesaid.border_bottom_color = defaultColor;
			someonesaid.border_bottom_style = BorderStyle.SOLID;
			someonesaid.border_bottom_width = 1;
			someonesaid.font_family = QyReaderApp.getFontFamily();
			someonesaid.padding = 5;
			someonesaid.text_indent = 10;
		}
		return someonesaid;
	}
	
	private static Summary summary;
	public static Summary getSummary() {
		if(null == summary){
			summary = new Summary();
			summary.margin_left = 28;
			summary.margin_right = 28;
		}
	    return summary;
    }
	
	public static void parse(Context context,String cssPath){
		if(TextUtils.isEmpty(cssPath)){
			return;
		}
        InputStream is = null;
        try {
            is = new FileInputStream(cssPath);
            parse(context, is);
        }
        catch (Exception e)
        {
        	System.err.println("CSS解析异常:"+e);
        }finally {
            if(null != is){
                try {
                    is.close();
                    is = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
	public static void parse(Context context,InputStream inputStream){
		if(null == inputStream){
			return;
		}
		InputStreamReader inputreader = null;
		BufferedReader buffreader = null;
		try {
			inputreader = new InputStreamReader(inputStream);
			buffreader = new BufferedReader(inputreader);
			String line;
			boolean hasNextParse = true;
			
			boolean hasBodyAttribute = false;
			boolean hasSummaryAttribute = false;
			boolean hasSomeonesaidAttribute = false;
			
			boolean hasBodyParseFinish = false;
			boolean hasSummaryParseFinish = false;
			boolean hasSomeonesaidParseFinish = false;
			//分行读取
//          while (( line = buffreader.readLine()) != null) { }
			while (hasNextParse) {
				line = buffreader.readLine();
				
				if(null != line && line.indexOf(Body.TAG_STYLE_ID) !=-1){
					hasBodyAttribute = true;
					body = new Body();
				}
				if(hasBodyAttribute && null != line){
					parseBodyAttribute(context,line, body);
					if(line.trim().equals("}")){
						hasBodyAttribute = false;
						hasBodyParseFinish = true;
					}
				}
				
				if(null != line && line.indexOf(Summary.TAG_STYLE_ID) !=-1){
					hasSummaryAttribute = true;
					summary = new Summary();
				}
				if(hasSummaryAttribute && null != line){
					parseSummaryAttribute(context,line, summary);
					hasSummaryAttribute = false;
					hasSummaryParseFinish = true;
				}
				
				if(null != line && line.indexOf(Someonesaid.TAG_STYLE_ID) !=-1){
					hasSomeonesaidAttribute = true;
					someonesaid = new Someonesaid();
				}
				if(hasSomeonesaidAttribute && null != line){
					parseSomeonesaidAttribute(context,line, someonesaid);
					if(line.trim().equals("}")){
						hasSomeonesaidAttribute = false;
						hasSomeonesaidParseFinish = true;
					}
				}
				
				if(hasBodyParseFinish && hasSummaryParseFinish && hasSomeonesaidParseFinish){
					hasNextParse = false;
//					Logger.d("CSS解析完成："+body.toString()+"\n"+summary.toString()+"\n"+someonesaid.toString());
					System.out.println("CSS解析完成："+body.toString()+"\n"+summary.toString()+"\n"+someonesaid.toString());
				}
			}
		}
		catch (Exception e)
		{
			System.err.println("CSS解析异常:"+e);
//			Logger.e("CSS解析异常",e);
		}finally {
			if(null != buffreader){
				try {
					buffreader.close();
					buffreader = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null != inputreader){
				try {
					inputreader.close();
					inputreader = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	private static void parseBodyAttribute(Context context,String line,Body object){
		if(line.indexOf(":") == -1 || null == object) return;
		final String[] values = line.split(":");
		final String key = values[0].trim();
		final String value = values[1].trim().replace(";", "");
		if(key.equals(Body.TAG_BACKGROUND)){
			object.background = value;
		}else if(key.equals(Body.TAG_FONT_SIZE)){
			object.font_size = parsePX(value);
		}else if(key.equals(Body.TAG_LINE_HEIGHT)){
			object.line_height = parsePX(value);
		}
	}
	private static void parseSummaryAttribute(Context context,String line,Summary object){
		if(TextUtils.isEmpty(line) || null == object) return;
		final String[] items = line.split(" ");
		for (int i = 0; i < items.length; i++)
        {
			if(TextUtils.isEmpty(items[i]) || items[i].indexOf(":") == -1){
				continue;
			}
			final String[] values = items[i].split(":");
			final String key = values[0].trim();
			final String value = values[1].trim().replace(";", "");
			if(key.equals(Summary.TAG_MARGIN_LEFT)){
				object.margin_left = parsePX(value);
			}else if(key.equals(Summary.TAG_MARGIN_RIGHT)){
				object.margin_right = parsePX(value);
			}
        }
	}
	private static void parseSomeonesaidAttribute(Context context,String line,Someonesaid object){
		if(line.indexOf(":") == -1 || null == object) return;
		final String[] values = line.split(":");
		final String key = values[0].trim();
		final String value = values[1].trim().replace(";", "");
		if(key.equals(Someonesaid.TAG_TEXT_INDENT)){
			object.text_indent = parsePX(value);
		}else if(key.equals(Someonesaid.TAG_PADDING)){
			object.padding = parsePX(value);
		}else if(key.equals(Someonesaid.TAG_BORDER_TOP_WIDTH)){
			object.border_top_width = parsePX(value);
		}else if(key.equals(Someonesaid.TAG_BORDER_TOP_STYLE)){
			object.border_top_style = parseBorderStyle(value);
		}else if(key.equals(Someonesaid.TAG_BORDER_TOP_COLOR)){
			object.border_top_color = value;
		}else if(key.equals(Someonesaid.TAG_BORDER_BOTTOM_WIDTH)){
			object.border_bottom_width = parsePX(value);
		}else if(key.equals(Someonesaid.TAG_BORDER_BOTTOM_STYLE)){
			object.border_bottom_style = parseBorderStyle(value);
		}else if(key.equals(Someonesaid.TAG_BORDER_BOTTOM_COLOR)){
			object.border_bottom_color = value;
		}else if(key.equals(Someonesaid.TAG_FONT_FAMILY) && value.indexOf("楷体") != -1){
			object.font_family = QyReaderApp.getFontFamily();
		}
	}
	private static int parsePX(String pxString){
		pxString = pxString.replace("px", "");
		int value = -1;
		try
        {
	        value = Integer.valueOf(pxString);
        }
        catch (NumberFormatException e)
        {
	        e.printStackTrace();
        }
		return value;
	}
	private static BorderStyle parseBorderStyle(String style){
		BorderStyle value = BorderStyle.SOLID;
		if(!TextUtils.isEmpty(style)){
			if(style.equals("solid")){
				value = BorderStyle.SOLID;
			}else if(style.equals("dashed")){
				value = BorderStyle.DASHED;
			}else if(style.equals("dotted")){
				value = BorderStyle.DOTTED;
			}else if(style.equals("double")){
				value = BorderStyle.DOUBLE;
			}
		}
		return value;
	}
	

	/** 解压css文件 */
	public static void unZipCSS(long bookId){
		final String savePath = EpubConst.EPUB_CSS_LOCAL_PATH+bookId+"/"+EpubConst.EPUB_CSS_NAME;
		final String epubPath = FileUtil.DownloadPath() + bookId + EpubConst.EPUB_SUFFIX;
		File file = new File(savePath); 
		if(file.exists()){
    		return;
    	}
		file.getParentFile().mkdirs();
		ZipInputStream inZip = null;
        try
        {
	        inZip = new ZipInputStream(new FileInputStream(epubPath));
	        ZipEntry zipEntry;    
	        String szName = "";    
	        boolean cssExists = false;
	        while ((zipEntry = inZip.getNextEntry()) != null && !cssExists) {    
	            szName = zipEntry.getName();    
	            if(!zipEntry.isDirectory() && szName.equals(EpubConst.EPUB_CSS_FULLNAME)){
	                file.createNewFile();    
	                FileOutputStream out = new FileOutputStream(file);    
	                int len;    
	                byte[] buffer = new byte[1024];    
	                while ((len = inZip.read(buffer)) != -1) {    
	                    out.write(buffer, 0, len);    
	                    out.flush();    
	                }    
	                out.close();  
	                cssExists = true;
	            }
	        }   
	        inZip.close(); 
	        Logger.d("css文件解压完成");
        }
        catch (Exception e)
        {
        	Logger.e("css文件解压异常："+e.getMessage());
	        e.printStackTrace();
        }
	}
}
